/**
 * 
 */
package vn.smartware.co.framework.connection;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import vn.smartware.co.framework.config.ActionMapping;
import vn.smartware.co.framework.config.ActionMappingsConfig;
import vn.smartware.co.framework.config.SystemConfig;
import vn.smartware.co.framework.exception.ClientException;
import vn.smartware.co.framework.exception.ServerException;
import vn.smartware.co.framework.exception.SessionTimeOutException;
import vn.smartware.co.framework.form.ActionForm;
import vn.smartware.co.framework.plugin.FileResource;
import vn.smartware.co.java.net.commons.Utils;
import vn.smartware.co.java.net.exception.JHTTPClientException;
import vn.smartware.co.java.net.exception.JHTTPServerException;
import vn.smartware.co.java.net.exception.TimeoutException;
import vn.smartware.co.java.net.http.JHTTPClient;


/**
 * HTTPConnectAction
 * @author thuctt
 */
public class HTTPConnectAction implements ConnectAction {
	
	private static Log log = LogFactory.getLog(HTTPConnectAction.class);	
	private String urlAddress = null;
	
	private FileResource fileResource;

	/**
	 * @param fileResource
	 */
	public HTTPConnectAction(FileResource fileResource) {
		super();
		this.fileResource = fileResource;
	}

	/**
	 * @param form
	 * @return ActionForm
	 * @throws ClientException 
	 * @throws ServerException 
	 * @throws SessionTimeOutException 
	 */
	public ActionForm executeRequest(ActionForm form) throws ClientException,
			ServerException, SessionTimeOutException {

		SystemConfig mapping = fileResource.getConfig();

		if (mapping == null) {
			log.error("Config read ERROR.");
			throw new ClientException("Config read ERROR.");
		}

		this.urlAddress = mapping.getWebServer().getUrl();

		form = httpConnect(form, mapping);

		return form;
	}
		
	/**
	 * 
	 * httpConnect: 
	 * @param form
	 * @param mapping
	 * @return ActionForm
	 * @throws MCSException
	 */
	private ActionForm httpConnect(ActionForm form, SystemConfig mapping)
			throws ClientException, ServerException, SessionTimeOutException {

		try {
			String formName = form.getActionForm();
			
			log.debug("ActionForm = " + formName);
			log.debug("ActionMethod = " + form.getActionMethod());
			
			if (Utils.isNullEmpty(formName)) {
				log.error("ActionForm is null.");
				return ActionMapping.setExceptionMessage(form, new ClientException(), "ActionForm is null");
			}
			
			ActionMappingsConfig actionMappingConfig = mapping.getActionMappingConfig(formName);
			
			if (actionMappingConfig == null) {
				log.error("ActionMappingsConfig is null.");
				return ActionMapping.setExceptionMessage(form, new ClientException(), "ActionMappingsConfig is null");
			}
			
			JHTTPClient client = new JHTTPClient(this.urlAddress);
			
			String timeout = actionMappingConfig.getTime();
			if (!Utils.isNullEmpty(timeout)){
				client.setTimeout(Integer.parseInt(timeout));
			}
			
			String scope = actionMappingConfig.getScope();
			if (!Utils.isNullEmpty(scope)){
				client.setScope(scope);
			}
			
			client.connect();
			
			client.sendRequest(form);
			
			Object obj = client.rcvResponceObject();
			
			client.disconnect();
			
			if (obj instanceof ActionForm) {
				return (ActionForm)obj;
			}
			
			ServerException e = (ServerException)obj;
			if (e.getCause().getClass().equals(SessionTimeOutException.class)){
				throw new SessionTimeOutException("SessionTimeOutException.", e);
			}
			
			throw new ServerException("ServerException.", e);
			
		} catch (JHTTPServerException e) {
			log.error("JHTTPServerException.", e);
			throw new ServerException("JHTTPServerException.", e);
		} catch (JHTTPClientException e) {
			log.error("JHTTPClientException.", e);
			throw new ClientException("JHTTPClientException.", e);
		} catch (TimeoutException e) {
			log.error("TimeoutException.", e);
			throw new SessionTimeOutException("TimeoutException.", e);
		}
	}
	
}
